package observable

import mapper.DataMapper
import mapper.DecorateObservable
import observable.threadpool.ThreadPoolFactory
import observer.Observer

/**
 * 再封装一层，以便拓展
 */
abstract class ObservableProxy<T> : Observable<T> {
    //上流是否使用线程
    private var subUseDispatcher: Boolean = false

    //下流是否使用线程
    private var observerUseDispatcher: Boolean = false

    override fun subscribe(observer: Observer<T>) {
        subscribeProxy(observer)
    }

    protected abstract fun subscribeProxy(observer: Observer<T>)

    /**
     * 返回一个新的to类型被观察者
     */
    fun <to> map(dataMapper: DataMapper<T, to>): ObservableProxy<to> {
        // 装饰当前对象，返回一个新的被观察者
        return DecorateObservable(this, dataMapper)
    }

    /**
     * 配置当前被观察者是否使用子线程
     */
    fun subscribeOnThread(useDispatcher: Boolean): ObservableProxy<T> {
        this.subUseDispatcher = useDispatcher
        //往上设置被观察者
        if (this is DecorateObservable<*, *>) {
            (this as DecorateObservable<*, *>).observable.subscribeOnThread(useDispatcher)
        }
        return this
    }


    /**
     * 配置观察者接收是否使用其他线程
     */
    fun observeOnThread(observerUseDispatcher: Boolean): ObservableProxy<T> {
        this.observerUseDispatcher = observerUseDispatcher
        //往上设置被观察者
        if (this is DecorateObservable<*, *>) {
            (this as DecorateObservable<*, *>).observable.observeOnThread(observerUseDispatcher)
        }
        return this
    }

    /**
     * 上流进行线程调度
     */
    fun dispatchSubscribe(command: Runnable) {
        if (subUseDispatcher) {//需要线程执行
            ThreadPoolFactory.getNewThreadPool().execute(command)
        } else {
            command.run()
        }
    }

    /**
     * 下流进行线程调度
     */
    fun dispatchObserve(command: Runnable) {
        if (observerUseDispatcher) {//需要线程执行
            ThreadPoolFactory.getDefaultPool().execute(command)
        } else {
            command.run()
        }
    }
}